package com.chen.utils.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.chen.base.utils.CommonUtil;
import com.chen.base.utils.ConvertUtil;
import com.chen.base.utils.RequiredUtil;
import com.chen.base.utils.StreamUtil;
import com.chen.base.utils.file.WebFileUtil;
import com.chen.base.utils.file.ZipUtil;
import com.chen.utils.entity.DataSourceInfo;
import com.chen.utils.entity.Fill;
import com.chen.utils.entity.StrategyInfo;
import com.chen.utils.mapper.DataSourceInfoMapper;
import com.chen.utils.mapper.StrategyInfoMapper;
import com.chen.utils.params.GenerateCodeParam;
import com.chen.utils.params.GeneratingParam;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 生成代码的前置参数检查操作
 * @author: ~龙~
 * @date: 2023/6/29 15:56
 **/
@Slf4j
@Component
public class GenerateBeforeHandler {

    @Resource
    private GenerateJavaFileHandler generateJavaFileHandler;
    @Resource
    private DataSourceInfoMapper dataSourceInfoMapper;
    @Resource
    private StrategyInfoMapper strategyInfoMapper;
    @Resource
    private HttpServletRequest request;

    @SneakyThrows
    public void handler(GeneratingParam gParam){
        // 查询数据源及策略配置
        DataSourceInfo dataSourceInfo = dataSourceInfoMapper.selectById(gParam.getDataSourceInfoId());
        StrategyInfo strategyInfo = strategyInfoMapper.selectById(gParam.getStrategyInfoId());

        // 构建参数
        GenerateCodeParam param = new GenerateCodeParam();
        ConvertUtil.convertor(dataSourceInfo, param);
        ConvertUtil.convertor(strategyInfo, param);
        param.setTableNameList(gParam.getTableNameList());

        // 忽略的表名前缀: 按逗号分隔
        if (strategyInfo != null && StrUtil.isNotBlank(strategyInfo.getIgnoreTablePrefixs())){
            List<String> ignoreTablePrefixs = Arrays.asList(strategyInfo.getIgnoreTablePrefixs().split(","));
            param.setIgnoreTablePrefixs(ignoreTablePrefixs);
        }

        // 参数检查并且设置默认值
        RequiredUtil.checkField(param, true);
        // 表名集检查
        param.getTableNameList().removeIf(String::isEmpty);

        // mybatis-plus属性自动填充处理
        List<Column> addTableFills = new ArrayList<>();
        if (strategyInfo != null && StrUtil.isNotBlank(strategyInfo.getFillsList())){
            List<Fill> fills = JSONArray.parseArray(strategyInfo.getFillsList(), Fill.class);
            for (Fill fp : fills) {
                StreamUtil.filterHandler(
                        Arrays.asList(FieldFill.values().clone()),
                        ff -> ff.toString().equalsIgnoreCase(fp.getFieldFillType()),
                        ff -> addTableFills.add(new Column(fp.getColumnName(), ff))
                );
            }
        }
        param.setAddTableFills(addTableFills);

        log.info("当前系统版本: {}", System.getProperty("os.name"));
        log.info("\n\n==========================生成代码 IP: {}==========================\n{}\n",
                ServletUtil.getClientIP(request), CommonUtil.toStr(param));

        // 生成java的相关文件夹和文件
        String outPath = generateJavaFileHandler.generatorFile(param);
        // 打包压缩成zip文件
        String zipPath = outPath + ".zip";
        ZipUtil.toZip(outPath, Files.newOutputStream(Paths.get(zipPath)));

        // 以文件流的形式输出到浏览器
        File file = new File(zipPath);
        WebFileUtil.downToClient(file);
        // 删除zip文件
        cn.hutool.core.io.FileUtil.del(file);
        // 删除文件夹
        cn.hutool.core.io.FileUtil.del(outPath);
    }
}
